﻿using NModbus;
using NModbus.Device;
using System;
using System.Net.Sockets;

public class ModbusTcpMasterWithLogging : ModbusMaster
{
    // 事件：发送请求时触发
    public event Action<byte[]> OnRequestSent;

    // 事件：接收到响应时触发
    public event Action<byte[]> OnResponseReceived;

    // 实际的 Modbus 主站实例（通过其 transport 属性继承）
    private readonly IModbusMaster _modbusMaster;

    // 构造函数，接收一个 IModbusMaster 实例并初始化
    public ModbusTcpMasterWithLogging(IModbusMaster modbusMaster)
        : base(modbusMaster.Transport)
    {
        _modbusMaster = modbusMaster;
    }

    // 覆盖 ReadHoldingRegisters 方法并捕获原始请求和响应
    public new ushort[] ReadHoldingRegisters(byte slaveAddress, ushort startAddress, ushort numRegisters)
    {
        // 获取原始请求包（字节数组）
        var request = BuildReadRequest(slaveAddress, startAddress, numRegisters);

        // 触发请求发送的事件
        OnRequestSent?.Invoke(request); // 发送请求前获取原始二进制包

        // 调用基类的 ReadHoldingRegisters 方法发送请求并获取响应
        ushort[] response = _modbusMaster.ReadHoldingRegisters(slaveAddress, startAddress, numRegisters);
        // 转换 response 从 ushort[] 到 byte[]
        byte[] responseBytes = ConvertUshortArrayToByteArray(response);
        // 触发响应接收的事件
        OnResponseReceived?.Invoke(responseBytes); // 接收到响应后获取原始二进制包

        return response;
    }
    private byte[] ConvertUshortArrayToByteArray(ushort[] ushortArray)
    {
        byte[] byteArray = new byte[ushortArray.Length * 2];
        for (int i = 0; i < ushortArray.Length; i++)
        {
            byteArray[i * 2] = (byte)(ushortArray[i] >> 8);  // 高字节
            byteArray[i * 2 + 1] = (byte)(ushortArray[i] & 0xFF);  // 低字节
        }
        return byteArray;
    }
    // 构建 Modbus 请求包
    private byte[] BuildReadRequest(byte slaveAddress, ushort startAddress, ushort numRegisters)
    {
        byte[] request = new byte[12]; // 模拟的包头大小，您可以根据需要调整

        // 填充请求包（根据 Modbus TCP 的包格式）
        request[0] = slaveAddress; // 单元标识符
        request[1] = 0x03; // 功能码：读取保持寄存器（0x03）
        request[2] = (byte)(startAddress >> 8); // 起始地址高字节
        request[3] = (byte)(startAddress & 0xFF); // 起始地址低字节
        request[4] = (byte)(numRegisters >> 8); // 寄存器数量高字节
        request[5] = (byte)(numRegisters & 0xFF); // 寄存器数量低字节

        // 在 Modbus TCP 中还需要包含事务 ID 和协议标识符等信息
        // 这里只是一个简单的包构建示例，您可以根据实际需要扩展它

        return request;
    }
}
